package com.getechnologiesmx.flutter.activity;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;

import java.util.ArrayList;
import java.util.Map;

public class Util {
    public static Intent toIntent(Map<String, Object> map) {
        Intent intent = new Intent();
        intent.setAction((String) map.get("action"));

        if (map.get("category") != null) {
            intent.addCategory((String) map.get("category"));
        }

        if (map.get("data") != null) {
            Uri data = Uri.parse((String) map.get("data"));
            intent.setData(data);
        }

        if (map.get("arguments") != null) {
            Map<String, Object> extras = (Map<String, Object>) map.get("arguments");
            intent.putExtras(Util.convertArguments(extras));
        }
        return intent;
    }

    public static Bundle convertArguments(Map<String, ?> arguments) {
        Bundle bundle = new Bundle();
        if (arguments == null) {
            return bundle;
        }
        for (String key : arguments.keySet()) {
            Object value = arguments.get(key);
            if (value instanceof Integer) {
                bundle.putInt(key, (Integer) value);
            } else if (value instanceof String) {
                bundle.putString(key, (String) value);
            } else if (value instanceof Boolean) {
                bundle.putBoolean(key, (Boolean) value);
            } else if (value instanceof Double) {
                bundle.putDouble(key, (Double) value);
            } else if (value instanceof Long) {
                bundle.putLong(key, (Long) value);
            } else if (value instanceof byte[]) {
                bundle.putByteArray(key, (byte[]) value);
            } else if (value instanceof int[]) {
                bundle.putIntArray(key, (int[]) value);
            } else if (value instanceof long[]) {
                bundle.putLongArray(key, (long[]) value);
            } else if (value instanceof double[]) {
                bundle.putDoubleArray(key, (double[]) value);
            } else if (isTypedArrayList(value, Integer.class)) {
                bundle.putIntegerArrayList(key, (ArrayList<Integer>) value);
            } else if (isTypedArrayList(value, String.class)) {
                bundle.putStringArrayList(key, (ArrayList<String>) value);
            } else if (isStringKeyedMap(value)) {
                bundle.putBundle(key, convertArguments((Map<String, ?>) value));
            } else {
                throw new UnsupportedOperationException("Unsupported type " + value);
            }
        }
        return bundle;
    }

    public static Bundle convertArrayArguments(Map<String, Object> arrayArguments) {
        Bundle bundle = new Bundle();
        if (arrayArguments == null) {
            return bundle;
        }
        for (String key : arrayArguments.keySet()) {
            Object value = arrayArguments.get(key);
            if (isTypedArrayList(value, Boolean.class)) {
                ArrayList<Boolean> list = (ArrayList<Boolean>) value;
                boolean[] array = new boolean[list.size()];
                for (int i = 0; i < list.size(); i++) {
                    array[i] = list.get(i);
                }
                bundle.putBooleanArray(key, array);
            } else if (isTypedArrayList(value, Integer.class)) {
                ArrayList<Integer> list = (ArrayList<Integer>) value;
                int[] array = new int[list.size()];
                for (int i = 0; i < list.size(); i++) {
                    array[i] = list.get(i);
                }
                bundle.putIntArray(key, array);
            } else if (isTypedArrayList(value, Long.class)) {
                ArrayList<Long> list = (ArrayList<Long>) value;
                long[] array = new long[list.size()];
                for (int i = 0; i < list.size(); i++) {
                    array[i] = list.get(i);
                }
                bundle.putLongArray(key, array);
            } else if (isTypedArrayList(value, Double.class)) {
                ArrayList<Double> list = (ArrayList<Double>) value;
                double[] array = new double[list.size()];
                for (int i = 0; i < list.size(); i++) {
                    array[i] = list.get(i);
                }
                bundle.putDoubleArray(key, array);
            } else if (isTypedArrayList(value, String.class)) {
                ArrayList<String> list = (ArrayList<String>) value;
                bundle.putStringArray(key, list.toArray(new String[list.size()]));
            } else {
                throw new UnsupportedOperationException("Unsupported type " + value);
            }
        }
        return bundle;
    }

    private static boolean isTypedArrayList(Object value, Class<?> type) {
        if (!(value instanceof ArrayList)) {
            return false;
        }
        ArrayList list = (ArrayList) value;
        for (Object o : list) {
            if (!(o == null || type.isInstance(o))) {
                return false;
            }
        }
        return true;
    }

    private static boolean isStringKeyedMap(Object value) {
        if (!(value instanceof Map)) {
            return false;
        }
        Map map = (Map) value;
        for (Object key : map.keySet()) {
            if (!(key == null || key instanceof String)) {
                return false;
            }
        }
        return true;
    }
}
